package main

import (
	"encoding/binary"
	"fmt"
	"io"
	"os"
)

// 二进制读写 都要为 导出字段
type Player struct {
	Name   [20]byte
	Age    int16 // 不使用 int 是因为其在不同cpu架构下长度可能不同
	Gender [6]byte
}

func directWriteADTToFile(path string, players []Player) error {

	f, err := os.Create(path)
	if err != nil {
		fmt.Println("open file failed:", err)
		return err
	}
	defer func() {
		f.Sync()
		f.Close()
	}()
	for _, player := range players {
		err = binary.Write(f, binary.BigEndian, &player) // 需要传指针
		if err != nil {
			return err
		}
	}

	return nil
}

func directReadADTFromFile(path string) error {

	f, err := os.Open(path)
	if err != nil {
		fmt.Println("open file failed :", err)
		return err
	}
	defer f.Close()
	var player Player
	for {
		err = binary.Read(f, binary.BigEndian, &player) // 需要传指针
		if err == io.EOF {
			fmt.Println("meet file EOF")
			return nil
		}
		if err != nil {
			fmt.Println("read file failed:", err)
			return err
		}
		fmt.Printf("%s %d %s\n", player.Name, player.Age, player.Gender)
	}

	return nil
}

func main() {
	var players [1]Player
	copy(players[0].Name[:], []byte("Tommy"))
	players[0].Age = 18
	copy(players[0].Gender[:], []byte("male"))
	file := "3.txt"

	err := directWriteADTToFile(file, players[:]) // [:]得到数组类型对应的切片
	if err != nil {
		fmt.Println("write file failed:", err)
		return
	}
	err = directReadADTFromFile(file)
	if err != nil {
		fmt.Println("read file failed :", err)
		return
	}

}
